#!/usr/bin/env python3
"""
Units MCP Server

面向 units 和 units_cur 命令行工具，提供单位转换和货币转换功能。

MCP tools 列表：
1. units_basic_options - 测试 units 基本选项（帮助、检查、数字精度、科学计数法）
   参数：option_type (str): 选项类型，如 "help", "check", "digits", "exponential"
   返回：统一的命令执行结果 JSON

2. units_file_options - 测试 units 文件相关选项
   参数：option_type (str): 选项类型，如 "file", "history", "log", "locale"
         filename (str): 文件名
   返回：统一的命令执行结果 JSON

3. units_format_options - 测试 units 格式选项
   参数：option_type (str): 选项类型，如 "oldstar", "newstar", "nolists", "show-factor", "output-format"
         format_str (str, optional): 输出格式字符串
   返回：统一的命令执行结果 JSON

4. units_output_modes - 测试 units 输出模式
   参数：option_type (str): 选项类型，如 "quiet", "strict", "verbose", "compact", "terse"
   返回：统一的命令执行结果 JSON

5. units_info_commands - 测试 units 信息命令
   参数：option_type (str): 选项类型，如 "terse", "round", "unitsfile", "version", "info"
   返回：统一的命令执行结果 JSON

6. units_special_units - 测试 units 特殊单位系统
   参数：option_type (str): 选项类型，如 "conformable", "units"
         unit_system (str, optional): 单位系统名称
   返回：统一的命令执行结果 JSON

7. units_currency - 测试 units_cur 货币转换工具
   参数：option_type (str): 选项类型，如 "help", "version", "verbose", "source", "base"
         value (str, optional): 源值或货币代码
   返回：统一的命令执行结果 JSON
"""

import subprocess
import json
from typing import Optional
from mcp.server.fastmcp import FastMCP, Context

mcp = FastMCP("Units MCP Server")

def run_command(command: str) -> dict:
    """执行命令并返回统一格式的结果"""
    try:
        result = subprocess.run(
            command, 
            shell=True, 
            capture_output=True, 
            text=True,
            timeout=30
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except subprocess.TimeoutExpired:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": "Command timed out after 30 seconds"
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Command execution failed: {str(e)}"
        }

@mcp.tool()
def units_basic_options(option_type: str) -> dict:
    """
    测试 units 基本选项
    
    参数:
        option_type: 选项类型，可选值: 
            "help" - 显示帮助信息
            "check" - 检查货币汇率
            "check-verbose" - 详细检查
            "digits" - 设置数字精度为8位
            "exponential" - 使用科学计数法
    
    返回:
        JSON结构: {
            "success": bool, 
            "command": str, 
            "exit_code": int, 
            "stdout": str, 
            "stderr": str
        }
    """
    option_map = {
        "help": ["-h", "--help"],
        "check": ["-c", "--check"],
        "check-verbose": ["--check-verbose", "--verbose-check"],
        "digits": ["-d 8", "--digits 8"],
        "exponential": ["-e", "--exponential"]
    }
    
    if option_type not in option_map:
        return {
            "success": False,
            "command": "",
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Invalid option_type: {option_type}. Must be one of: {list(option_map.keys())}"
        }
    
    commands = []
    for opt in option_map[option_type]:
        if option_type in ["digits", "exponential"]:
            # 对于交互式命令，使用 echo 模拟输入
            cmd = f"echo -e '1\\n5\\nexit' | units {opt}"
        else:
            cmd = f"units {opt}"
        commands.append(cmd)
    
    # 执行第一个命令作为示例
    return run_command(commands[0])

@mcp.tool()
def units_file_options(option_type: str, filename: str = "test.txt") -> dict:
    """
    测试 units 文件相关选项
    
    参数:
        option_type: 选项类型，可选值:
            "file" - 使用指定文件
            "history" - 设置历史文件
            "log" - 设置日志文件
            "locale" - 设置本地化文件
        filename: 文件名
    
    返回:
        JSON结构: {
            "success": bool, 
            "command": str, 
            "exit_code": int, 
            "stdout": str, 
            "stderr": str
        }
    """
    option_map = {
        "file": ["-f", "--file"],
        "history": ["-H", "--history"],
        "log": ["-L", "--log", "-l", "--locale"]
    }
    
    if option_type not in option_map:
        return {
            "success": False,
            "command": "",
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Invalid option_type: {option_type}. Must be one of: {list(option_map.keys())}"
        }
    
    # 使用第一个选项格式
    opt = option_map[option_type][0]
    cmd = f"echo -e '1\\n5\\nexit' | units {opt} {filename}"
    
    return run_command(cmd)

@mcp.tool()
def units_format_options(option_type: str, format_str: Optional[str] = None) -> dict:
    """
    测试 units 格式选项
    
    参数:
        option_type: 选项类型，可选值:
            "oldstar" - 使用旧星号格式
            "newstar" - 使用新星号格式  
            "nolists" - 不显示列表
            "show-factor" - 显示转换因子
            "output-format" - 设置输出格式
        format_str: 输出格式字符串（仅对output-format有效）
    
    返回:
        JSON结构: {
            "success": bool, 
            "command": str, 
            "exit_code": int, 
            "stdout": str, 
            "stderr": str
        }
    """
    option_map = {
        "oldstar": ["--oldstar"],
        "newstar": ["--newstar", "-n", "--nolists"],
        "show-factor": ["-S", "--show-factor"],
        "output-format": ["-o", "--output-format"]
    }
    
    if option_type not in option_map:
        return {
            "success": False,
            "command": "",
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Invalid option_type: {option_type}. Must be one of: {list(option_map.keys())}"
        }
    
    opt = option_map[option_type][0]
    
    if option_type == "output-format" and format_str:
        cmd = f"echo -e '1\\n7\\nexit' | units {opt} {format_str}"
    else:
        cmd = f"echo -e '1\\n5\\nexit' | units {opt}"
    
    return run_command(cmd)

@mcp.tool()
def units_output_modes(option_type: str) -> dict:
    """
    测试 units 输出模式
    
    参数:
        option_type: 选项类型，可选值:
            "quiet" - 安静模式
            "strict" - 严格模式
            "verbose" - 详细模式
            "compact" - 紧凑模式
            "terse" - 简洁模式
    
    返回:
        JSON结构: {
            "success": bool, 
            "command": str, 
            "exit_code": int, 
            "stdout": str, 
            "stderr": str
        }
    """
    option_map = {
        "quiet": ["-q", "--quiet", "--silent"],
        "strict": ["-s", "--strict"],
        "verbose": ["-v", "--verbose"],
        "compact": ["--compact"],
        "terse": ["-t", "--terse"]
    }
    
    if option_type not in option_map:
        return {
            "success": False,
            "command": "",
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Invalid option_type: {option_type}. Must be one of: {list(option_map.keys())}"
        }
    
    opt = option_map[option_type][0]
    
    if option_type in ["quiet", "terse"]:
        cmd = f"echo -e '1\\n5' | units {opt}"
    else:
        cmd = f"echo -e '1\\n5\\nexit' | units {opt}"
    
    return run_command(cmd)

@mcp.tool()
def units_info_commands(option_type: str) -> dict:
    """
    测试 units 信息命令
    
    参数:
        option_type: 选项类型，可选值:
            "terse" - 简洁输出
            "round" - 四舍五入
            "unitsfile" - 显示单位文件路径
            "version" - 显示版本信息
            "info" - 显示程序信息
    
    返回:
        JSON结构: {
            "success": bool, 
            "command": str, 
            "exit_code": int, 
            "stdout": str, 
            "stderr": str
        }
    """
    option_map = {
        "terse": ["-t", "--terse"],
        "round": ["-r", "--round"],
        "unitsfile": ["-U", "--unitsfile"],
        "version": ["-V", "--version"],
        "info": ["-I", "--info"]
    }
    
    if option_type not in option_map:
        return {
            "success": False,
            "command": "",
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Invalid option_type: {option_type}. Must be one of: {list(option_map.keys())}"
        }
    
    opt = option_map[option_type][0]
    
    if option_type in ["terse"]:
        cmd = f"echo -e '1\\n5' | units {opt}"
    elif option_type in ["round"]:
        cmd = f"echo -e '1\\n5\\nexit' | units {opt}"
    else:
        cmd = f"units {opt}"
    
    return run_command(cmd)

@mcp.tool()
def units_special_units(option_type: str, unit_system: Optional[str] = None) -> dict:
    """
    测试 units 特殊单位系统
    
    参数:
        option_type: 选项类型，可选值:
            "conformable" - 一致性检查
            "units" - 指定单位系统
        unit_system: 单位系统名称（仅对units选项有效）
    
    返回:
        JSON结构: {
            "success": bool, 
            "command": str, 
            "exit_code": int, 
            "stdout": str, 
            "stderr": str
        }
    """
    if option_type == "conformable":
        cmd = "echo -e '1\\n5\\nexit' | units --conformable"
    elif option_type == "units":
        system = unit_system or "gauss"
        cmd = f"echo -e '1\\n5\\nexit' | units --units {system}"
    else:
        return {
            "success": False,
            "command": "",
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Invalid option_type: {option_type}. Must be 'conformable' or 'units'"
        }
    
    return run_command(cmd)

@mcp.tool()
def units_currency(option_type: str, value: Optional[str] = None) -> dict:
    """
    测试 units_cur 货币转换工具
    
    参数:
        option_type: 选项类型，可选值:
            "help" - 显示帮助
            "version" - 显示版本
            "verbose" - 详细模式
            "source" - 设置数据源
            "base" - 设置基准货币
        value: 源值或货币代码
    
    返回:
        JSON结构: {
            "success": bool, 
            "command": str, 
            "exit_code": int, 
            "stdout": str, 
            "stderr": str
        }
    """
    option_map = {
        "help": ["-h", "--help"],
        "version": ["-V", "--version"],
        "verbose": ["-v", "--verbose"],
        "source": ["-s", "--source"],
        "base": ["-b", "--base"]
    }
    
    if option_type not in option_map:
        return {
            "success": False,
            "command": "",
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Invalid option_type: {option_type}. Must be one of: {list(option_map.keys())}"
        }
    
    opt = option_map[option_type][0]
    
    if option_type in ["source", "base"] and value:
        cmd = f"units_cur {opt} {value}"
    else:
        cmd = f"units_cur {opt}"
    
    return run_command(cmd)

if __name__ == "__main__":
    mcp.run()